Skip to content

caiovitorsantos/exportify

Repository files navigation

Exportify

Downloads a Spotify playlist as MP3 files with proper ID3 tags (title, artist, album, year, track number, genre).

Requirements

  • Ruby 3.3+
  • yt-dlpbrew install yt-dlp
  • Python 3 + mutagenpip3 install mutagen
  • A Spotify Developer application
  • Para playlists ou vídeos únicos do YouTube/YouTube Music não é necessária nenhuma credencial adicional — só o yt-dlp.

Setup

  1. Crie um app em developer.spotify.com.
  2. Adicione http://127.0.0.1:8888/callback como Redirect URI nas configurações do app.
  3. Instale as dependências:
make install

Isso verifica a versão do Ruby, instala o yt-dlp (via Homebrew no macOS ou apt no Linux), instala o mutagen (Python) e roda bundle install. Cada etapa pode ser rodada isoladamente (make check-ruby, make install-yt-dlp, make install-mutagen, make bundle) — veja make help para a lista completa. Se preferir instalar manualmente, veja a seção Requirements acima.

  1. Execute o setup interativo:
bin/exportify init
=== Exportify Setup ===

Diretório principal [musics]: ~/Music
Spotify Client ID: <seu client id>
Spotify Client Secret: ████████

Configuração salva em ~/.exportify

As credenciais e o diretório ficam salvos em ~/.exportify (permissão 600). Para reconfigurar qualquer campo, execute init novamente — Enter em branco mantém o valor atual.

Alternativa: as variáveis de ambiente SPOTIFY_CLIENT_ID e SPOTIFY_CLIENT_SECRET têm prioridade sobre o arquivo de configuração, útil em ambientes de CI.

Usage

Baixar uma playlist

bin/exportify https://open.spotify.com/playlist/<playlist_id>

Os arquivos são organizados em subdiretórios pelo nome da playlist:

musics/
  Rock dos Anos 80/
    Queen - Bohemian Rhapsody.mp3
    David Bowie - Heroes.mp3
  Trap Brasil/
    ...

Faixas que já existem no disco são ignoradas automaticamente. Rodar o comando novamente após adicionar músicas à playlist baixa apenas as novas.

Baixar uma playlist do YouTube ou YouTube Music

exportify https://www.youtube.com/playlist?list=<id>
exportify https://music.youtube.com/playlist?list=<id>

Para playlists privadas, use --browser para reaproveitar os cookies de um navegador logado no YouTube:

exportify https://www.youtube.com/playlist?list=<id> --browser=chrome

Quando o vídeo tem metadado oficial (YouTube Music / Content ID), artista, álbum e ano são extraídos diretamente; caso contrário, o artista é extraído do padrão "Artista - Título" no título do vídeo (com fallback para o nome do canal), e o nome da playlist é usado como álbum. O campo gênero sempre fica em branco (o YouTube não expõe esse dado). As flags --retag e --sync funcionam da mesma forma que para playlists do Spotify.

Nota: para obter esses metadados completos, a busca da playlist não usa mais o modo "flat" do yt-dlp, o que torna a listagem de playlists grandes (centenas de faixas) mais lenta — o yt-dlp precisa resolver os metadados de cada vídeo antes de começar a baixar.

Baixar um vídeo único do YouTube (com capítulos)

exportify "https://www.youtube.com/watch?v=<id>"

Se o vídeo tiver capítulos declarados (comum em mixes e compilações, onde cada capítulo marca o início de uma música), o exportify baixa o vídeo uma única vez e separa automaticamente em um MP3 por capítulo, com artista extraído do título do capítulo (padrão "Artista - Título", com fallback para o canal) e álbum = título do vídeo. Sem capítulos, baixa como uma faixa única. As flags --retag, --sync e --browser funcionam da mesma forma que para playlists.

Sincronização bidirecional

Para remover do disco as músicas que foram retiradas da playlist:

bin/exportify https://open.spotify.com/playlist/<playlist_id> --sync

Regravar tags ID3

Para atualizar as tags dos arquivos já baixados sem rebaixar:

bin/exportify https://open.spotify.com/playlist/<playlist_id> --retag

Visualizar playlists baixadas (app web)

Para navegar pelas playlists e músicas já baixadas em um painel web:

bin/exportify web

Abre um servidor local em http://localhost:4567 com a lista de playlists, as faixas de cada uma e os detalhes (tags ID3, duração, tamanho) com player de áudio. Para usar outra porta:

bin/exportify web --port 8080

App somente leitura — os downloads continuam sendo feitos via CLI (bin/exportify <url>).

Desenvolvimento

bundle exec rake test      # testes
bundle exec rubocop        # lint
bundle exec bundler-audit check --update  # vulnerabilidades em dependências

O CI roda os três automaticamente a cada push.

Release

Para publicar uma nova versão no RubyGems:

  1. Atualize lib/exportify/version.rb
  2. Crie e faça push da tag:
git tag v1.0.0
git push --tags

O workflow de release dispara automaticamente e publica a gem. Requer o secret RUBYGEMS_API_KEY configurado em Settings → Secrets → Actions do repositório.

Veja o CHANGELOG.md para o histórico de versões.

Notas

  • O token OAuth é cacheado em ~/.exportify_token.json e renovado automaticamente quando expira. Se a sessão for revogada, o arquivo é removido e um novo login é solicitado.
  • Playlists de artistas oficiais ou gravadoras podem retornar erro 403 — isso é uma restrição da API do Spotify para apps de terceiros sem acesso estendido.
  • A dependência webrick (usada só para o servidor local de callback OAuth do login com Spotify) tem uma vulnerabilidade conhecida sem patch disponível ainda (CVE-2026-38969, request smuggling). O risco prático é baixo aqui: o servidor roda só em 127.0.0.1, atende uma única requisição do próprio navegador do usuário durante o login, e não fica atrás de nenhum proxy — não há a cadeia proxy→backend que esse tipo de ataque explora. Reavaliar quando uma versão corrigida do webrick for lançada.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors